package com.jie.service;

import com.jie.dao.FileDao;
import com.jie.show.FileInfo;
import com.jie.mapper.FileMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.UUID;


@Service
public class FileService {

    // 读取配置文件
    @Value("${file.upload.dir}")
    private String fileUploadDir;

    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private FileDao fileDao;


    /**
     * 文件上传业务
     *
     * @param
     * @return
     */
    public List<FileInfo> getMyInfo(){
        List<FileInfo> res = fileMapper.getMyInfo();
        if (res != null){
            return res;
        }else {
            return null;
        }
    }



    public FileInfo upload(MultipartFile multipartFile) {
        // 防止配置的时候文件夹不加后缀/
        if (!fileUploadDir.endsWith("/")) {
            fileUploadDir += "/";
        }
        File dir = new File(fileUploadDir);
        // 如果文件夹不存在，就创建文件夹
        if (!dir.exists()) {
            dir.mkdirs();
        }
        FileInfo fileInfo = new FileInfo();
        try {
            // 根据文件内容计算文件MD5，防止重复文件多次上传
            String md5 = DigestUtils.md5DigestAsHex(multipartFile.getBytes());
            // 如果当前文件内容已经有记录了，直接返回文件记录，不再上传
            FileInfo existsFile = fileMapper.getFileInfoByMD5(md5);
            if (existsFile != null) {
                return existsFile;
            }
            // 获取文件后缀名
            String fileType = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().indexOf("."));
            // 文件存储在服务器时，使用随机码防止重名问题
            String fileName = UUID.randomUUID() + fileType;
            // 保存文件到配置的路径中
            multipartFile.transferTo(new File(fileUploadDir + fileName));
            // 文件记录保存原文件名
            fileInfo.setName(multipartFile.getOriginalFilename());
            // 文件记录保存md5
            fileInfo.setMd5(md5);
            // 文件存放路径，用于下载的时候读取文件
            fileInfo.setPath(fileUploadDir + fileName);
            // 文件类型（后缀名）
            fileInfo.setType(fileType);
            // 后端获取文件的接口地址（见FileController）
            fileInfo.setUrl("/api/file/" + md5);
            // 文件大小
            fileInfo.setSize(multipartFile.getSize());
            // 保存文件记录并返回
            fileMapper.createFileInfo(fileInfo);
            return fileInfo;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 文件下载业务（抄就完事了）
     *
     * @param res
     * @param md5
     */
    public void download(HttpServletResponse res, String md5) {
        FileInfo record = fileMapper.getFileInfoByMD5(md5);
        if (".apk".equals(record.getType())) {
            res.setCharacterEncoding("UTF-8");
            res.setContentType("application/force-download");
            res.setContentType("multipart/form-data");
        } else {
            res.setCharacterEncoding("utf-8");
            res.setContentType("text/html;charset=utf-8");
            res.setContentType("multipart/form-data");
        }
        String fileNameEncord = null;
        try {
            fileNameEncord = URLEncoder.encode(record.getName() == null ?
                    record.getType().substring(1) : record.getName(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        res.setHeader("Content-Disposition", "attachment;filename=" + fileNameEncord);
        byte[] buff = new byte[2048];
        InputStream bis = null;
        OutputStream os;
        try {
            os = res.getOutputStream();
            bis = new FileInputStream(record.getPath());
            res.setContentLength(bis.available());
            int i;
            while ((i = bis.read(buff)) > 0) {
                os.write(buff, 0, i);
            }
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public List<FileInfo> getMyMusic(String name){
        List<FileInfo> list = fileMapper.getMyMusic(name);
        if (list != null){
            return list;
        }else {
            return null;
        }
    }
}
